<?php


namespace app\common\lib;

use think\facade\Cache;
use think\Exception;

class Code
{
    /** @var int 获取验证码的最大次数 */
    private static $max_code_num = 5;
    /** @var float|int 验证码的有效时长 */
    private static $code_time = 60*60;

    /**
     * 验证码
     * code_data:[
     *  "code": 验证码
     *  "time": 验证码有效时间
     *  "num" : 当天获取验证码次数
     * ]
     */
    public static function set_code($key,$code=""){
        $code_data = json_decode(Cache::get($key),true);

        // 已过当天，刷新次数
        $today_time = strtotime(date("Y-m-d",time()));
        if($code_data['time']< $today_time ){
            $code_data['num'] = 0;
        }

        //校验最大次数
        if($code_data && $code_data['num']>=self::$max_code_num){
            throw new Exception("已超过最大次数，无法再获取");
        }
        //验证码
        $code = $code?$code:rand(100000,999999);
        //获取次数加1
        $num = isset($code_data['num'])? ($code_data['num']+1) : 1;
        $code_data = [
            "code"=>$code,
            "num"=>$num,
            "time"=>time(),
        ];
        // 判断过期时间是否超过当天，如果超过当天则保存为过期时长，不然则保存至当天24点
        $time = strtotime("+1 day") - time();
        $time = $time<self::$code_time ? self::$code_time:$time;
        Cache::set($key,json_encode($code_data),$time);
        return $code;
    }
    /** 校验验证码 */
    public static function check_code($key,$code){
        $code_data = json_decode(Cache::get($key),true);
        if(!$code_data || !$code_data['code']) throw new Exception("验证码不存在,请重新获取!");
        if((time()-$code_data['time']) > self::$code_time) throw new Exception("验证码已过期，请重新获取！");
        if($code_data['code'] != $code) throw new Exception("验证码错误！");

        // 删除验证码
        $code_data['code'] = "";
        // 判断过期时间是否超过当天，如果超过当天则保存为过期时长，不然则保存至当天24点
        $today_time = strftime(date("Y-m-d",time()));
        if($code_data['time']< $today_time ){
            $code_data['num'] = 0;
        }
        $time = strtotime("+1 day") - time();
        $time = $time<self::$code_time ? self::$code_time:$time;
        Cache::set($key,json_encode($code_data),$time);

        return true;
    }
}